package redis_client

import (
	"context"
	"github.com/go-redis/redis/v8"
	"log"
	"server/cfg"
	"time"
)

var (
	client *redis.Client
)

func r() *redis.Client {
	if client == nil {
		client = redis.NewClient(&redis.Options{
			Addr:     cfg.Config.Redis.Addr,
			Password: cfg.Config.Redis.Password,
			DB:       cfg.Config.Redis.DB,
			PoolSize: cfg.Config.Redis.PoolSize,
		})
		// 测试连接
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		_, err := client.Ping(ctx).Result()
		if err != nil {
			log.Println("redis 连接失败：", err)
		}
	}
	return client
}

func Close() {
	err := r().Close()
	if err != nil {
		log.Println("redis 关闭失败：", err)
	}
}

// ==================== 基本操作 ====================

// Set 设置键值
func Set(ctx context.Context, key string, value any, expiration time.Duration) error {
	return r().Set(ctx, key, value, expiration).Err()
}

// Get 获取键值
func Get(ctx context.Context, key string) (string, error) {
	return r().Get(ctx, key).Result()
}

// Del 删除键
func Del(ctx context.Context, keys ...string) (int64, error) {
	return r().Del(ctx, keys...).Result()
}

// Exists 检查键是否存在
func Exists(ctx context.Context, keys ...string) (int64, error) {
	return r().Exists(ctx, keys...).Result()
}

// Expire 设置键的过期时间
func Expire(ctx context.Context, key string, expiration time.Duration) (bool, error) {
	return r().Expire(ctx, key, expiration).Result()
}

// ==================== 哈希操作 ====================

// HSet 设置哈希字段
func HSet(ctx context.Context, key string, values ...any) (int64, error) {
	return r().HSet(ctx, key, values...).Result()
}

// HGet 获取哈希字段
func HGet(ctx context.Context, key, field string) (string, error) {
	return r().HGet(ctx, key, field).Result()
}

// HGetAll 获取所有哈希字段
func HGetAll(ctx context.Context, key string) (map[string]string, error) {
	return r().HGetAll(ctx, key).Result()
}

// ==================== 列表操作 ====================

// LPush 左推入列表
func LPush(ctx context.Context, key string, values ...any) (int64, error) {
	return r().LPush(ctx, key, values...).Result()
}

// RPop 右弹出列表
func RPop(ctx context.Context, key string) (string, error) {
	return r().RPop(ctx, key).Result()
}

// ==================== 集合操作 ====================

// SAdd 添加集合元素
func SAdd(ctx context.Context, key string, members ...any) (int64, error) {
	return r().SAdd(ctx, key, members...).Result()
}

// SMembers 获取集合所有元素
func SMembers(ctx context.Context, key string) ([]string, error) {
	return r().SMembers(ctx, key).Result()
}

// ==================== 有序集合操作 ====================

// ZAdd 添加有序集合元素
func ZAdd(ctx context.Context, key string, members ...*redis.Z) (int64, error) {
	return r().ZAdd(ctx, key, members...).Result()
}

// ZRange 获取有序集合范围
func ZRange(ctx context.Context, key string, start, stop int64) ([]string, error) {
	return r().ZRange(ctx, key, start, stop).Result()
}

// ==================== 分布式锁 ====================

// AcquireLock 获取分布式锁
func AcquireLock(ctx context.Context, key string, value any, expiration time.Duration) (bool, error) {
	return r().SetNX(ctx, key, value, expiration).Result()
}

// ReleaseLock 释放分布式锁
func ReleaseLock(ctx context.Context, key string) error {
	return r().Del(ctx, key).Err()
}

// ==================== 发布订阅 ====================

// Publish 发布消息
func Publish(ctx context.Context, channel string, message any) (int64, error) {
	return r().Publish(ctx, channel, message).Result()
}

// Subscribe 订阅频道
func Subscribe(ctx context.Context, channels ...string) *redis.PubSub {
	return r().Subscribe(ctx, channels...)
}
